package ru.amse.stroganova.ui.tool.state;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;

import ru.amse.stroganova.presentation.EdgePresentation;
import ru.amse.stroganova.presentation.VertexPresentation;
import ru.amse.stroganova.ui.GraphComponent;
import ru.amse.stroganova.ui.command.Command;
import ru.amse.stroganova.ui.tool.Tool;
import ru.amse.stroganova.ui.visual.ImaginaryEdge;

class EdgeEndEditingState extends ToolState {

	private final GraphComponent component;
	
	private final Tool tool;
	
	private final EdgePresentation oldEdge;
	
	private final ImaginaryEdge imaginaryEdge;
	
	private final VertexPresentation oldSource;
	
	private final VertexPresentation oldDestin;
	
	private final boolean isSourceFixed;
	
	private final Command oldEdgeDeleteCommand;
	
	EdgeEndEditingState(GraphComponent component, Tool parentTool, EdgePresentation edge, boolean isSourceFixed) {
		this.component = component;
		tool = parentTool;
		oldEdge = edge;
		this.isSourceFixed = isSourceFixed;
		oldSource = component.getGraphPresentation().getPresentationForVertex(edge.getEdge().getSource());
		oldDestin = component.getGraphPresentation().getPresentationForVertex(edge.getEdge().getDestination());
		if (isSourceFixed) {
			imaginaryEdge = new ImaginaryEdge(oldSource.getCenter(), oldDestin.getCenter(), isSourceFixed, component.getGraphPresentation().isDirected(), component.getGraphPresentation().isWeighted(), oldEdge.getWeight());
		} else {
			imaginaryEdge = new ImaginaryEdge(oldDestin.getCenter(), oldSource.getCenter(), isSourceFixed, component.getGraphPresentation().isDirected(), component.getGraphPresentation().isWeighted(), oldEdge.getWeight());
		}
		component.getGraphElementSelection().unselect();
		component.getGraphElementSelection().selectEdge(oldEdge);
		oldEdgeDeleteCommand = component.getCommandFactory().getNewDeleteCommand();
		oldEdgeDeleteCommand.execute();
	}
	
	@Override
	public void mouseReleased(MouseEvent e) {
		VertexPresentation newVertex = component.getGraphElementSelection().getVertex(e.getPoint());
		
		if (newVertex != null) {
			if (isSourceFixed) {
				if (!newVertex.equals(oldDestin)  && !component.getGraphPresentation().areConnected(oldSource, newVertex)) {
					Command command = component.getCommandFactory().getNewEdgeEndEditCommand(oldEdge, oldSource, newVertex);
					component.addCommand(command);
					command.execute();
				} else {
					oldEdgeDeleteCommand.undo();
				}
			} else {
				if (!newVertex.equals(oldSource)  && !component.getGraphPresentation().areConnected(newVertex, oldDestin)) {
					Command command = component.getCommandFactory().getNewEdgeEndEditCommand(oldEdge, newVertex, oldDestin);
					component.addCommand(command);
					command.execute();
				} else {
					oldEdgeDeleteCommand.undo();
				}
			}
		} else {
			oldEdgeDeleteCommand.undo();
		}
		component.repaint();
		tool.setState(new DefaultState(component, tool));
	}
	
	@Override
	public void mouseDragged(MouseEvent e) {
		imaginaryEdge.moveEnd(e.getPoint());
		component.repaint();
	}
	
	@Override
	public void paint(Graphics g, Color backgroundColor) {
		imaginaryEdge.paint(g, backgroundColor);
	}

}
